using Microsoft.EntityFrameworkCore;
using SheLife.Domain.Entities;
using SheLife.Infrastructure.Data;

namespace SheLife.Infrastructure.Repositories
{
    /// <summary>
    /// 成长记录仓储实现
    /// </summary>
    public class GrowthRecordRepository : Repository<GrowthRecord>, IGrowthRecordRepository
    {
        public GrowthRecordRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<GrowthRecord>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(g => g.UserId == userId).OrderByDescending(g => g.RecordDate).ToListAsync();
        }

        public async Task<IEnumerable<GrowthRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.RecordDate >= startDate && g.RecordDate <= endDate).ToListAsync();
        }

        public async Task<IEnumerable<GrowthRecord>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.Category == category).OrderByDescending(g => g.RecordDate).ToListAsync();
        }

        public async Task<GrowthRecord?> GetByUserIdAndDateAsync(Guid userId, DateTime date)
        {
            return await _dbSet.FirstOrDefaultAsync(g => g.UserId == userId && g.RecordDate.Date == date.Date);
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var records = await _dbSet
                .Where(g => g.UserId == userId)
                .GroupBy(g => g.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return records.ToDictionary(r => r.Category, r => r.Count);
        }

        public async Task<Dictionary<DateTime, int>> GetDailyRecordCountAsync(Guid userId, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);

            var records = await _dbSet
                .Where(g => g.UserId == userId && g.RecordDate >= startDate && g.RecordDate <= endDate)
                .ToListAsync();

            var result = new Dictionary<DateTime, int>();
            for (var date = startDate; date <= endDate; date = date.AddDays(1))
            {
                var dayRecords = records.Where(r => r.RecordDate.Date == date.Date);
                result[date] = dayRecords.Count();
            }

            return result;
        }
    }

    /// <summary>
    /// 目标管理仓储实现
    /// </summary>
    public class GoalRepository : Repository<Goal>, IGoalRepository
    {
        public GoalRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<Goal>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(g => g.UserId == userId).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<Goal>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.Category == category).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<Goal>> GetByUserIdAndStatusAsync(Guid userId, string status)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.Status == status).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<Goal>> GetActiveGoalsAsync(Guid userId)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.Status != "completed" && g.Status != "cancelled").OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var goals = await _dbSet
                .Where(g => g.UserId == userId)
                .GroupBy(g => g.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return goals.ToDictionary(g => g.Category, g => g.Count);
        }

        public async Task<Dictionary<string, int>> GetStatusStatisticsAsync(Guid userId)
        {
            var goals = await _dbSet
                .Where(g => g.UserId == userId)
                .GroupBy(g => g.Status)
                .Select(g => new { Status = g.Key, Count = g.Count() })
                .ToListAsync();

            return goals.ToDictionary(g => g.Status, g => g.Count);
        }
    }

    /// <summary>
    /// 目标进度仓储实现
    /// </summary>
    public class GoalProgressRepository : Repository<GoalProgress>, IGoalProgressRepository
    {
        public GoalProgressRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<GoalProgress>> GetByGoalIdAsync(Guid goalId)
        {
            return await _dbSet.Where(p => p.GoalId == goalId).OrderBy(p => p.RecordDate).ToListAsync();
        }

        public async Task<IEnumerable<GoalProgress>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(p => p.UserId == userId).OrderByDescending(p => p.RecordDate).ToListAsync();
        }

        public async Task<IEnumerable<GoalProgress>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            return await _dbSet.Where(p => p.UserId == userId && p.RecordDate >= startDate && p.RecordDate <= endDate).ToListAsync();
        }

        public async Task<GoalProgress?> GetLatestByGoalIdAsync(Guid goalId)
        {
            return await _dbSet.Where(p => p.GoalId == goalId).OrderByDescending(p => p.RecordDate).FirstOrDefaultAsync();
        }

        public async Task<Dictionary<Guid, double>> GetGoalProgressPercentageAsync(IEnumerable<Guid> goalIds)
        {
            var result = new Dictionary<Guid, double>();

            foreach (var goalId in goalIds)
            {
                var progresses = await _dbSet.Where(p => p.GoalId == goalId).ToListAsync();
                if (progresses.Any())
                {
                    var totalProgress = progresses.Sum(p => p.ProgressValue);
                    var maxProgress = progresses.Max(p => p.TargetValue);
                    var percentage = maxProgress > 0 ? (totalProgress / maxProgress) * 100 : 0;
                    result[goalId] = Math.Round(percentage, 2);
                }
                else
                {
                    result[goalId] = 0;
                }
            }

            return result;
        }
    }

    /// <summary>
    /// 学习计划仓储实现
    /// </summary>
    public class LearningPlanRepository : Repository<LearningPlan>, ILearningPlanRepository
    {
        public LearningPlanRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<LearningPlan>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(l => l.UserId == userId).OrderByDescending(l => l.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlan>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(l => l.UserId == userId && l.Category == category).OrderByDescending(l => l.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlan>> GetByUserIdAndStatusAsync(Guid userId, string status)
        {
            return await _dbSet.Where(l => l.UserId == userId && l.Status == status).OrderByDescending(l => l.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlan>> GetActivePlansAsync(Guid userId)
        {
            return await _dbSet.Where(l => l.UserId == userId && l.Status != "completed" && l.Status != "cancelled").OrderByDescending(l => l.CreatedAt).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var plans = await _dbSet
                .Where(l => l.UserId == userId)
                .GroupBy(l => l.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return plans.ToDictionary(p => p.Category, p => p.Count);
        }

        public async Task<Dictionary<string, int>> GetStatusStatisticsAsync(Guid userId)
        {
            var plans = await _dbSet
                .Where(l => l.UserId == userId)
                .GroupBy(l => l.Status)
                .Select(g => new { Status = g.Key, Count = g.Count() })
                .ToListAsync();

            return plans.ToDictionary(p => p.Status, p => p.Count);
        }
    }

    /// <summary>
    /// 学习计划任务仓储实现
    /// </summary>
    public class LearningPlanTaskRepository : Repository<LearningPlanTask>, ILearningPlanTaskRepository
    {
        public LearningPlanTaskRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<LearningPlanTask>> GetByPlanIdAsync(Guid planId)
        {
            return await _dbSet.Where(t => t.PlanId == planId).OrderBy(t => t.Order).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlanTask>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(t => t.UserId == userId).OrderByDescending(t => t.DueDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlanTask>> GetByUserIdAndStatusAsync(Guid userId, string status)
        {
            return await _dbSet.Where(t => t.UserId == userId && t.Status == status).OrderByDescending(t => t.DueDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlanTask>> GetOverdueTasksAsync(Guid userId)
        {
            var now = DateTime.UtcNow;
            return await _dbSet.Where(t => t.UserId == userId && t.Status != "completed" && t.DueDate < now).OrderBy(t => t.DueDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningPlanTask>> GetUpcomingTasksAsync(Guid userId, int days = 7)
        {
            var now = DateTime.UtcNow;
            var endDate = now.AddDays(days);
            return await _dbSet.Where(t => t.UserId == userId && t.Status != "completed" && t.DueDate >= now && t.DueDate <= endDate).OrderBy(t => t.DueDate).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetStatusStatisticsAsync(Guid userId)
        {
            var tasks = await _dbSet
                .Where(t => t.UserId == userId)
                .GroupBy(t => t.Status)
                .Select(g => new { Status = g.Key, Count = g.Count() })
                .ToListAsync();

            return tasks.ToDictionary(t => t.Status, t => t.Count);
        }
    }

    /// <summary>
    /// 学习记录仓储实现
    /// </summary>
    public class LearningRecordRepository : Repository<LearningRecord>, ILearningRecordRepository
    {
        public LearningRecordRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<LearningRecord>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(l => l.UserId == userId).OrderByDescending(l => l.LearningDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            return await _dbSet.Where(l => l.UserId == userId && l.LearningDate >= startDate && l.LearningDate <= endDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningRecord>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(l => l.UserId == userId && l.Category == category).OrderByDescending(l => l.LearningDate).ToListAsync();
        }

        public async Task<IEnumerable<LearningRecord>> GetByTaskIdAsync(Guid taskId)
        {
            return await _dbSet.Where(l => l.TaskId == taskId).OrderByDescending(l => l.LearningDate).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var records = await _dbSet
                .Where(l => l.UserId == userId)
                .GroupBy(l => l.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return records.ToDictionary(r => r.Category, r => r.Count);
        }

        public async Task<Dictionary<DateTime, double>> GetDailyLearningTimeAsync(Guid userId, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);

            var records = await _dbSet
                .Where(l => l.UserId == userId && l.LearningDate >= startDate && l.LearningDate <= endDate)
                .ToListAsync();

            var result = new Dictionary<DateTime, double>();
            for (var date = startDate; date <= endDate; date = date.AddDays(1))
            {
                var dayRecords = records.Where(r => r.LearningDate.Date == date.Date);
                var totalTime = dayRecords.Sum(r => r.DurationMinutes);
                result[date] = totalTime;
            }

            return result;
        }

        public async Task<double> GetTotalLearningTimeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            var records = await _dbSet
                .Where(l => l.UserId == userId && l.LearningDate >= startDate && l.LearningDate <= endDate)
                .ToListAsync();

            return records.Sum(r => r.DurationMinutes);
        }
    }

    /// <summary>
    /// 习惯养成仓储实现
    /// </summary>
    public class HabitRepository : Repository<Habit>, IHabitRepository
    {
        public HabitRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<Habit>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(h => h.UserId == userId).OrderByDescending(h => h.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<Habit>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(h => h.UserId == userId && h.Category == category).OrderByDescending(h => h.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<Habit>> GetActiveHabitsAsync(Guid userId)
        {
            return await _dbSet.Where(h => h.UserId == userId && h.IsActive).OrderByDescending(h => h.CreatedAt).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var habits = await _dbSet
                .Where(h => h.UserId == userId)
                .GroupBy(h => h.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return habits.ToDictionary(h => h.Category, h => h.Count);
        }
    }

    /// <summary>
    /// 习惯记录仓储实现
    /// </summary>
    public class HabitRecordRepository : Repository<HabitRecord>, IHabitRecordRepository
    {
        public HabitRecordRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<HabitRecord>> GetByHabitIdAsync(Guid habitId)
        {
            return await _dbSet.Where(r => r.HabitId == habitId).OrderBy(r => r.RecordDate).ToListAsync();
        }

        public async Task<IEnumerable<HabitRecord>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(r => r.UserId == userId).OrderByDescending(r => r.RecordDate).ToListAsync();
        }

        public async Task<IEnumerable<HabitRecord>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            return await _dbSet.Where(r => r.UserId == userId && r.RecordDate >= startDate && r.RecordDate <= endDate).ToListAsync();
        }

        public async Task<HabitRecord?> GetByHabitIdAndDateAsync(Guid habitId, DateTime date)
        {
            return await _dbSet.FirstOrDefaultAsync(r => r.HabitId == habitId && r.RecordDate.Date == date.Date);
        }

        public async Task<Dictionary<Guid, int>> GetHabitCompletionCountAsync(IEnumerable<Guid> habitIds, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);

            var records = await _dbSet
                .Where(r => habitIds.Contains(r.HabitId) && r.RecordDate >= startDate && r.RecordDate <= endDate && r.IsCompleted)
                .ToListAsync();

            var result = new Dictionary<Guid, int>();
            foreach (var habitId in habitIds)
            {
                var count = records.Count(r => r.HabitId == habitId);
                result[habitId] = count;
            }

            return result;
        }

        public async Task<Dictionary<Guid, double>> GetHabitCompletionRateAsync(IEnumerable<Guid> habitIds, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);
            var totalDays = (endDate - startDate).Days + 1;

            var records = await _dbSet
                .Where(r => habitIds.Contains(r.HabitId) && r.RecordDate >= startDate && r.RecordDate <= endDate)
                .ToListAsync();

            var result = new Dictionary<Guid, double>();
            foreach (var habitId in habitIds)
            {
                var habitRecords = records.Where(r => r.HabitId == habitId).ToList();
                var completedCount = habitRecords.Count(r => r.IsCompleted);
                var rate = totalDays > 0 ? (completedCount / (double)totalDays) * 100 : 0;
                result[habitId] = Math.Round(rate, 2);
            }

            return result;
        }

        public async Task<Dictionary<DateTime, int>> GetDailyCompletedHabitsAsync(Guid userId, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);

            var records = await _dbSet
                .Where(r => r.UserId == userId && r.RecordDate >= startDate && r.RecordDate <= endDate && r.IsCompleted)
                .ToListAsync();

            var result = new Dictionary<DateTime, int>();
            for (var date = startDate; date <= endDate; date = date.AddDays(1))
            {
                var dayRecords = records.Where(r => r.RecordDate.Date == date.Date);
                result[date] = dayRecords.Count();
            }

            return result;
        }
    }

    /// <summary>
    /// 习惯打卡组仓储实现
    /// </summary>
    public class HabitGroupRepository : Repository<HabitGroup>, IHabitGroupRepository
    {
        public HabitGroupRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<HabitGroup>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(g => g.UserId == userId).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<HabitGroup>> GetByUserIdAndIsActiveAsync(Guid userId, bool isActive)
        {
            return await _dbSet.Where(g => g.UserId == userId && g.IsActive == isActive).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<IEnumerable<HabitGroup>> GetPublicGroupsAsync()
        {
            return await _dbSet.Where(g => g.IsPublic).OrderByDescending(g => g.CreatedAt).ToListAsync();
        }

        public async Task<Dictionary<Guid, int>> GetGroupMemberCountAsync(IEnumerable<Guid> groupIds)
        {
            var result = new Dictionary<Guid, int>();

            foreach (var groupId in groupIds)
            {
                var count = await _context.Set<HabitGroupMember>()
                    .Where(m => m.GroupId == groupId)
                    .CountAsync();
                result[groupId] = count;
            }

            return result;
        }
    }

    /// <summary>
    /// 习惯打卡组成员仓储实现
    /// </summary>
    public class HabitGroupMemberRepository : Repository<HabitGroupMember>, IHabitGroupMemberRepository
    {
        public HabitGroupMemberRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<HabitGroupMember>> GetByGroupIdAsync(Guid groupId)
        {
            return await _dbSet.Where(m => m.GroupId == groupId).ToListAsync();
        }

        public async Task<IEnumerable<HabitGroupMember>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(m => m.UserId == userId).ToListAsync();
        }

        public async Task<HabitGroupMember?> GetByGroupIdAndUserIdAsync(Guid groupId, Guid userId)
        {
            return await _dbSet.FirstOrDefaultAsync(m => m.GroupId == groupId && m.UserId == userId);
        }

        public async Task<bool> IsUserInGroupAsync(Guid groupId, Guid userId)
        {
            return await _dbSet.AnyAsync(m => m.GroupId == groupId && m.UserId == userId);
        }
    }

    /// <summary>
    /// 情绪日记仓储实现
    /// </summary>
    public class EmotionJournalRepository : Repository<EmotionJournal>, IEmotionJournalRepository
    {
        public EmotionJournalRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<EmotionJournal>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(j => j.UserId == userId).OrderByDescending(j => j.JournalDate).ToListAsync();
        }

        public async Task<IEnumerable<EmotionJournal>> GetByUserIdAndDateRangeAsync(Guid userId, DateTime startDate, DateTime endDate)
        {
            return await _dbSet.Where(j => j.UserId == userId && j.JournalDate >= startDate && j.JournalDate <= endDate).ToListAsync();
        }

        public async Task<EmotionJournal?> GetByUserIdAndDateAsync(Guid userId, DateTime date)
        {
            return await _dbSet.FirstOrDefaultAsync(j => j.UserId == userId && j.JournalDate.Date == date.Date);
        }

        public async Task<IEnumerable<EmotionJournal>> GetByUserIdAndEmotionAsync(Guid userId, string emotion)
        {
            return await _dbSet.Where(j => j.UserId == userId && j.Emotion == emotion).OrderByDescending(j => j.JournalDate).ToListAsync();
        }

        public async Task<Dictionary<string, int>> GetEmotionStatisticsAsync(Guid userId)
        {
            var journals = await _dbSet
                .Where(j => j.UserId == userId)
                .GroupBy(j => j.Emotion)
                .Select(g => new { Emotion = g.Key, Count = g.Count() })
                .ToListAsync();

            return journals.ToDictionary(j => j.Emotion, j => j.Count);
        }

        public async Task<Dictionary<DateTime, int>> GetDailyJournalCountAsync(Guid userId, int days = 30)
        {
            var endDate = DateTime.UtcNow.Date;
            var startDate = endDate.AddDays(-days);

            var journals = await _dbSet
                .Where(j => j.UserId == userId && j.JournalDate >= startDate && j.JournalDate <= endDate)
                .ToListAsync();

            var result = new Dictionary<DateTime, int>();
            for (var date = startDate; date <= endDate; date = date.AddDays(1))
            {
                var dayJournals = journals.Where(j => j.JournalDate.Date == date.Date);
                result[date] = dayJournals.Count();
            }

            return result;
        }
    }

    /// <summary>
    /// 成就徽章仓储实现
    /// </summary>
    public class AchievementBadgeRepository : Repository<AchievementBadge>, IAchievementBadgeRepository
    {
        public AchievementBadgeRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<AchievementBadge>> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.Where(b => b.UserId == userId).OrderByDescending(b => b.EarnedDate).ToListAsync();
        }

        public async Task<IEnumerable<AchievementBadge>> GetByUserIdAndCategoryAsync(Guid userId, string category)
        {
            return await _dbSet.Where(b => b.UserId == userId && b.Category == category).OrderByDescending(b => b.EarnedDate).ToListAsync();
        }

        public async Task<AchievementBadge?> GetByUserIdAndBadgeCodeAsync(Guid userId, string badgeCode)
        {
            return await _dbSet.FirstOrDefaultAsync(b => b.UserId == userId && b.BadgeCode == badgeCode);
        }

        public async Task<bool> HasBadgeAsync(Guid userId, string badgeCode)
        {
            return await _dbSet.AnyAsync(b => b.UserId == userId && b.BadgeCode == badgeCode);
        }

        public async Task<Dictionary<string, int>> GetCategoryStatisticsAsync(Guid userId)
        {
            var badges = await _dbSet
                .Where(b => b.UserId == userId)
                .GroupBy(b => b.Category)
                .Select(g => new { Category = g.Key, Count = g.Count() })
                .ToListAsync();

            return badges.ToDictionary(b => b.Category, b => b.Count);
        }

        public async Task<Dictionary<DateTime, int>> GetMonthlyBadgeCountAsync(Guid userId, int months = 12)
        {
            var endDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1);
            var startDate = endDate.AddMonths(-months);

            var badges = await _dbSet
                .Where(b => b.UserId == userId && b.EarnedDate >= startDate && b.EarnedDate < endDate)
                .ToListAsync();

            var result = new Dictionary<DateTime, int>();
            for (var date = startDate; date < endDate; date = date.AddMonths(1))
            {
                var monthBadges = badges.Where(b => b.EarnedDate.Year == date.Year && b.EarnedDate.Month == date.Month);
                result[date] = monthBadges.Count();
            }

            return result;
        }
    }

    /// <summary>
    /// 成长档案仓储实现
    /// </summary>
    public class GrowthProfileRepository : Repository<GrowthProfile>, IGrowthProfileRepository
    {
        public GrowthProfileRepository(SheLifeDbContext context) : base(context)
        {
        }

        public async Task<GrowthProfile?> GetByUserIdAsync(Guid userId)
        {
            return await _dbSet.FirstOrDefaultAsync(p => p.UserId == userId);
        }

        public async Task<Dictionary<string, object>> GetProfileStatisticsAsync(Guid userId)
        {
            var profile = await GetByUserIdAsync(userId);
            if (profile == null)
            {
                return new Dictionary<string, object>();
            }

            var statistics = new Dictionary<string, object>
            {
                { "TotalGoals", profile.TotalGoals },
                { "CompletedGoals", profile.CompletedGoals },
                { "TotalLearningHours", profile.TotalLearningHours },
                { "TotalHabits", profile.TotalHabits },
                { "CurrentStreak", profile.CurrentStreak },
                { "LongestStreak", profile.LongestStreak },
                { "TotalBadges", profile.TotalBadges }
            };

            return statistics;
        }

        public async Task UpdateStatisticsAsync(Guid userId, Dictionary<string, object> statistics)
        {
            var profile = await GetByUserIdAsync(userId);
            if (profile == null)
            {
                profile = new GrowthProfile
                {
                    UserId = userId,
                    TotalGoals = 0,
                    CompletedGoals = 0,
                    TotalLearningHours = 0,
                    TotalHabits = 0,
                    CurrentStreak = 0,
                    LongestStreak = 0,
                    TotalBadges = 0,
                    LastUpdated = DateTime.UtcNow
                };
                await _dbSet.AddAsync(profile);
            }
            else
            {
                if (statistics.ContainsKey("TotalGoals"))
                    profile.TotalGoals = Convert.ToInt32(statistics["TotalGoals"]);
                
                if (statistics.ContainsKey("CompletedGoals"))
                    profile.CompletedGoals = Convert.ToInt32(statistics["CompletedGoals"]);
                
                if (statistics.ContainsKey("TotalLearningHours"))
                    profile.TotalLearningHours = Convert.ToDouble(statistics["TotalLearningHours"]);
                
                if (statistics.ContainsKey("TotalHabits"))
                    profile.TotalHabits = Convert.ToInt32(statistics["TotalHabits"]);
                
                if (statistics.ContainsKey("CurrentStreak"))
                    profile.CurrentStreak = Convert.ToInt32(statistics["CurrentStreak"]);
                
                if (statistics.ContainsKey("LongestStreak"))
                    profile.LongestStreak = Convert.ToInt32(statistics["LongestStreak"]);
                
                if (statistics.ContainsKey("TotalBadges"))
                    profile.TotalBadges = Convert.ToInt32(statistics["TotalBadges"]);
                
                profile.LastUpdated = DateTime.UtcNow;
                _dbSet.Update(profile);
            }

            await _context.SaveChangesAsync();
        }
    }
}